package jxtcp

import (
	"errors"
	"fmt"
	"time"

	"gitee.com/frankwangli/jxmap"
	"github.com/vmihailenco/msgpack/v5"
)

// Client 客户端结构体
type Client struct {
	address          string
	count            int
	conn             []*ClientConn
	messageList      chan *Message
	returnMessageMap *jxmap.JxMap[string, *CliengMessage]
	overTime         int
	MachineId        uint32
}
type CliengMessage struct {
	ReturnData   chan []byte
	Progressbar  chan *Progress
	OtherMessage chan *Message
}

func NewClient(address string, count int, mid uint32) *Client {
	outData := &Client{
		address:          address,
		count:            count,
		conn:             make([]*ClientConn, 0),
		messageList:      make(chan *Message, 100),
		returnMessageMap: jxmap.New[string, *CliengMessage](),
		overTime:         0,
		MachineId:        mid,
	}
	outData.Init()
	return outData
}
func (c *Client) SetOverTime(value int) {
	c.overTime = value
}
func (c *Client) GetCount() int {
	return len(c.conn)
}
func (c *Client) Init() {
	for i := 0; i < c.count; i++ {
		conn := NewClientConn(c.address, c.MachineId, func(m *Message) {
			ch, ok := c.returnMessageMap.Get(m.Id)
			if ok {
				switch m.Type {
				case 0: //正常的消息回复
					ch.ReturnData <- m.Data
				case 1: //进度条类消息返回
					p := new(Progress)
					err := msgpack.Unmarshal(m.Data, &p)
					if err == nil {
						ch.Progressbar <- p
					} else {
						fmt.Println("消息不是进度消息")
					}
				case 2: //其他消息需要通知到
				}
			}
		})
		c.conn = append(c.conn, conn)
	}
}
func (c *Client) SendMessage(m *Message, progress func(p *Progress), onmsg ...func(m *Message)) ([]byte, error) {
	sended := false
	value := &CliengMessage{
		ReturnData:   make(chan []byte),    // 必须
		Progressbar:  make(chan *Progress), // 必须
		OtherMessage: make(chan *Message),  // 移除，若未使用
	}
	c.returnMessageMap.Set(m.Id, value)
	defer func() {
		c.returnMessageMap.Delete(m.Id)
		close(value.ReturnData)
		close(value.Progressbar)
		close(value.OtherMessage)
	}() // 确保释放资源
	for {
		for _, val := range c.conn {
			ok := val.SendMessage(m)
			if ok {
				sended = true
				break
			}
		}
		time.Sleep(time.Millisecond * 200)
		if sended {
			break
		}
	}
	for {
		select {
		case data := <-value.ReturnData:
			return data, nil
		case p := <-value.Progressbar:
			if progress != nil {
				progress(p)
			}
		case msg := <-value.OtherMessage:
			if len(onmsg) > 0 {
				onmsg[0](msg)
			}
		case <-timeoutChannel(c.overTime):
			return nil, errors.New("链接超时")
		}
	}
}
func timeoutChannel(overTime int) <-chan time.Time {
	if overTime > 0 {
		return time.After(time.Duration(overTime) * time.Millisecond)
	}
	return nil // 如果 overTime == 0，则返回 nil，表示不启用超时
}
